<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>

<br>
<br>
<br>
<script>
    let aa = {
        a: 1
    }
    let bb = Object.assign({}, aa)
    aa['a'] = 2

    // console.log(bb,aa)

    // 标准盒模型中width指的是内容区域content的宽度；height指的是内容区域content的高度。
    // 怪异盒模型中的width指的是内容、边框、内边距总的宽度（content + border + padding）；height指的是内容、边框、内边距总的高度
    let arr = ['push', 'pop', 'slice', 'shift', 'unshift', 'splice']

    let agesarr = [1, 3, 6, 8, 8, 6, 2]
    // console.log(agesarr.slice(1,3)) //切割出新的数据[3,6]
    // console.log(agesarr) //原数组不变

    // console.log(agesarr.splice(1,1,56)) //第三个之后数组插入 
    // console.log(agesarr) //原数组改变

    // console.log(agesarr.splice(1,3)) //从下标1截取到下表3的新数组
    // console.log(agesarr) //改变原来的数组

    // console.log(Array.isArray(arr))//检索是否是数组
    var s = Array.prototype,
        s1 = Object.create(s)
    arr.map((i) => {
        s1[i] = function() {
            var a = Array.prototype.slice.call(arguments)
            // console.log(a)
            // console.log(a instanceof Array)
        }
        s1[i]()
    })

    //   console.log(s1)




    // for (var k in arr) {
    // console.log(arr[k])
    // }
    // console.log(typeof arr) object

    // var objecto={a:1,b:2}
    // console.log(objecto.hasOwnProperty('a'))//检索是否有key
    // console.log(Object.keys(objecto))//把key转化为数组

    // ------ 深拷贝  JSON.parse(JSON.stringify(data))会丢失里面的函数------ 缺点：据说如果数据深度 > 1000+ 会爆栈 方法一
    // 深浅拷贝的区别就是前者将原数据重新复制了一份然后新开了一个地址，后者则是将原数据的引用地址拷贝了一份而已
    // let obj = {
    //     name: 'zj',
    //     age: 18,
    //     grendr: {
    //         num: 12,
    //         list: [0, 12, 3, 0],
    //         listObj: {
    //             ore: 'res',
    //             message: '成功',
    //             list: [
    //                 1, 2, 3, {
    //                     a: 1,
    //                     b: 2
    //                 }
    //             ]
    //         }
    //     },
    //     test: function() {},
    //    a:[3,2,1]
    // }
    // function clone(obj, tar) {
    //     var tar = tar || {};
    //     var type = Object.prototype.toString;
    //     for (var k in obj) {
    //         if (obj.hasOwnProperty(k)) {
    //             if (typeof obj[k] === 'object' && obj[k] != null) {
    //                 tar[k] = type.call(obj[k]) === '[object Array]' ? [] : {};
    //                 clone(obj[k], tar[k]);
    //             } else {
    //                 tar[k] = obj[k];
    //             }
    //         }
    //     }
    //     console.log(tar)
    //     return tar
    // }
    // console.log(clone(obj, {}),'--------------')
    // 数组中对象根据id排序
    // var sortobj =[{id:1,age:2},{id:6,age:6},{id:5,age:5},{id:4,age:4},{id:2,age:2}]
    //         function listSort(sortobj){
    //             for(let i=0;i<sortobj.length;i++){
    //                 for(let j=0;j<sortobj.length-1-i;j++){
    //                     if(sortobj[j]['id']>sortobj[j+1]['id']){
    //                         var temp = sortobj[j]
    //                         sortobj[j] = sortobj[j+1]
    //                         sortobj[j+1] = temp
    //                     }
    //                 }
    //             }
    //         return(sortobj)
    //         }
    //        console.log( listSort(sortobj))

    // 数组冒泡排序
    // var examplearr=[96,4,15,2,0];
    // function sortArr(orginArr) {
    //     var arr = orginArr;
    //     var len = arr.length;
    //     for(var i = 0; i < len; ++i) {
    //         console.log(i)
    //         for(var j =0; j < len -1 - i;++j) {
    //             if(arr[j]>arr[j+1]) {
    //                 var temp = arr[j];
    //                 arr[j] = arr[j+1];
    //                 arr[j+1] = temp
    //             }
    //             console.log(arr)
    //         }
    //     }
    //     return arr;
    // }
    // console.log(sortArr(examplearr)); 



    // 使用lodash函数库来进行深拷贝 方法二
    //  src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"
    // let data = {
    // name: '严家辉',
    // age: 18,
    // other: {
    //     gender: "男"
    // }
    //     }
    //     const aa = () => {
    //         // 核心代码
    //         let data1 = _.cloneDeep(data)
    //         data1.name = '隔壁小花'
    //         data1.other.gender = '女'
    //         console.log('a函数',data1)
    //     }
    //     const b = () => console.log('b函数',data) // 老严
    //     aa()
    //     b()


    // jq来进行深拷贝 方法三
    // src="http://code.jquery.com/jquery-2.1.1.min.js"let data = {
    //     name: '严家辉',
    //     age: 18,
    //     other: {
    //         gender: "男"
    //     }
    // }
    // const a = () => {
    //     // 核心代码
    //     let data1 = $.extend(true,{},data);
    //     data1.name = '隔壁老王'
    //     data1.other.gender = '女'
    //     console.log('a函数',data1)
    // }
    // const b = () => console.log('b函数',data) // 老严
    // a()
    // b()

    // ------浅拷贝 -----------
    // 浅拷贝方法一
    // const deepCopy = obj => {
    //     let result = typeof obj.splice === "function" ? [] : {};
    //     if (obj && typeof obj === 'object') {
    //         for (let key in obj) {
    //             // 我们直接去掉递归，让第二层的数据直接赋值（引用地址）
    //              result[key] = obj[key];
    //         }
    //         return result;
    //     }
    //     return obj;
    // }
    // let data = {
    //     name: '严家辉',
    //     age: 18,
    //     other: {
    //         gender: "男"
    //     }
    // }
    // const a = () => {
    //     let data1 = deepCopy(data);
    //     data1.name = '隔壁老王'
    //     data1.other.gender = '女'
    //     console.log('a函数',data1)
    // }
    // const b = () => console.log('b函数',data) // 老严
    // a()
    // b()

    // 浅拷贝方法二
    // let data = {
    //     name: '严家辉',
    //     age: 18,
    //     other: {
    //         gender: "男"
    //     }
    // }
    // const a = () => {
    //     // 核心代码
    //     let data1 = Object.assign({},data);
    //     data1.name = '城中村村花'
    //     data1.other.gender = '女'
    //     console.log('a函数',data1)
    // }
    // const b = () => console.log('b函数',data) // 老严
    // a()
    // b()


    //------ 如何判断两个对象（不定顺序的key）是否相等呢？------
    // const objArrobj = { a: 1, b: 2, c: 3 };
    // let a = Object.keys(objArrobj)//把key变为一个数组
    // console.log(a.includes('a')) //includes查找数组中是否有这个元素

    // let msgobj1 = {
    //     name: '严家辉',
    //     age: 18
    // }
    // let msgobj2 = {
    //     age: 18,
    //     name: '严家辉'
    // }
    // var obj1keys = Object.keys(msgobj1);  
    // var obj2keys = Object.keys(msgobj2);
    // var isSame = (obj1keys, obj2keys) => {
    //     if (obj2keys.length !== obj1keys.length) return false;
    //     for (let i = 0; i <= obj1keys.length - 1; i++) {
    //         let key = obj1keys[i];
    //         if (!obj2keys.includes(key)) return false
    //         if (msgobj2[key] !==msgobj2[key]) return false
    //     }
    //     return true
    // }
    // console.log(isSame(obj1keys, obj2keys))





    //------ es6 generator ------
    // function* geners() {
    //     var y = yield 0 + 0;
    //     console.log(y)

    //     var c =  yield 1
    //     console.log(c)

    //     var z = yield z+2
    //     console.log(z)
    // }
    // var nex = geners()
    // nex.next()
    // nex.next(2333) //遇到yield 语句会停止 传的参数会赋值
    // nex.next(23)

    // es6 new set()去重
    // let array = [1,2,2,2,2,2,2,2,2,3,6,6,8,4,5,6,54,2]
    // let setarr = new Set(array)
    // let newArr = Array.from(setarr);
    // console.log(newArr)

    // es6 Object.assign()合并
    // let obj12 = {a:1}
    // let obj2 = {c:2}
    // let obj3 = Object.assign(obj12,obj2)
    // console.log(obj3)


    // 闭包

    function fun(n, o) {
        return {
            fun: function(m) {
                return fun(m, n);
            }
        };
    }
    fun(0)



    //   a.fun(2); 
    //    a.fun(3)
    // ------防抖节流 ------
    function debounce(fn, delay) {
        let timer = null //借助闭包
        return function() {
            if (timer) {
                clearTimeout(timer);
            }
            timer = setTimeout(fn, delay); // 简化写法
        }
    }
    // 然后是旧代码--
    function showTop() {
        var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
        console.log('滚动条位置：' + scrollTop);
    }
    window.onscroll = debounce(showTop, 1000);

    //------判断类型------
    // typeof instanceof
    // instanceof 返回布尔值
    // var arr2 = []
    // var obj2 = {}
    // console.log(arr2 instanceof Array) //true
    // console.log(obj2 instanceof Object) //true
    // console.log(arr2 instanceof Object) //true Array 是 object 的子类。


    //------ vue3 响应原理es6 proxy------
    // var target = {
    //     name: 'poetries',
    //     age:128
    // };
    // var logHandler = {
    // get: function(target, key ,receiver) { //receiver原对象
    //     console.log(`${key} 被读取`);
    //     return target[key];
    // },
    // set: function(target, key, value,receiver) {
    //     console.log(`${key} 被设置为 ${value}`);
    //     target[key] = value;
    // }
    // }

    // var targetWithLog = new Proxy(target, logHandler);

    // console.log(targetWithLog)
    // targetWithLog.name; // 控制台输出：name 被读取
    // targetWithLog.name = 'others'; // 控制台输出：name 被设置为 others
    //  // 控制台输出: others
    // setTimeout(function(){
    //     targetWithLog.name = 'others'
    // },1000)

    //------ vue2 响应原理Object.defineProperfty------
    //     let _obj={ 
    //          val :123
    //     }
    //     Object.defineProperty(_obj,'val',{
    //         get:function(){
    //             console.log('获取')
    //         },
    //         set:function(){
    //             console.log('设置')
    //         }
    //     })
    //    _obj.val
    //    _obj.val=0

    // ------ Object.defineProperty封转------
    // function createProperty(obj) {
    //     let keys = Object.keys(obj);
    //     keys.forEach((item) => {
    //         objFn(obj, item, obj[item])
    //     })
    //     return obj;
    // }

    // function objFn(obj, item, val) {
    //     Object.defineProperty(obj, item, {
    //         get() {
    //             console.log(`${item}获取`)
    //         },
    //         set(newVal) {
    //             console.log(`${item}设置`)
    //             val = newVal
    //             // obj[item] = newVal
    //         }
    //     }) 
    //     return obj;
    // }
    // var c = {
    //     a: 1,
    //     b: 2
    // }
    // let car = createProperty(c)
    // //a获取
    // car.a 
    // //b设置的
    // car.b = 11111;



    //------ this 指向------
    // 普通函数指向 window
    // 构造函数指向 该构造函数
    // 箭头函数指向上下文
    // call第一个作用可以调用函数
    // var o={}
    // function fn(a,b){
    //     console.log(this)
    //     console.log(a+b)
    // }
    // fn(1,2) //普通函数指向window
    // fn.call(o,1,2) //call指向第一个参数


    // call主要作用可以实现继承
    //    function father(uname,age,sex){
    //         console.log(this,'father') //指向实例函数
    //         this.uname = uname;
    //         this.age = age
    //         this.sex = sex;
    //     }
    //     function Son(uname,age,sex){
    //         console.log(this,'son')
    //         father.call(this,uname,age,sex);
    //     }
    //     var son = new Son('刘德华',18,'男');
    // apply主要作用与claa一样第二个参数为一个数组
    //      function aply(usermsg){
    //         console.log(this) //this指向Aplys
    //         this.username = username[0]
    //         this.age = username[1]
    //         this.sex = username[2]
    //      }
    //      function Aplys(usermsg){
    //         console.log(this)
    //         //  aply(usermsg)
    //         aply.apply(this,username)
    //      }
    //     let username=['张三',25,'男']
    //     let userAllMsg = new Aplys(username)
    //  bind

    //  function aply(usermsg,age,sex){
    //     console.log(this) //this指向Aplys
    //     this.username = usermsg
    //     this.age = age
    //     this.sex = sex
    //  }
    //  function Aplys(usermsg,age,sex){
    //     console.log(this)
    //     // aply(usermsg)
    //     aply.bind(this,usermsg,age,sex)() //调用后执行不调用 不用执行
    //  }
    // let usermsg = '张三',
    //     age = 15,
    //     sex = '男'
    // let userAllMsg = new Aplys(usermsg,age,sex)




    // ------原型原型链------
    // 属性名称
    // prototype 原型
    // __proto__ 原型链

    // 从属关系
    // prototype 函数的一个属性:对象{} 原型链继承原型 原型不继承原型链
    // __proto__ 对象Object的一个属性:对象的{}
    // 对象的__proto__保存着该对象的构造函数的 prototype
    function A() {
        this.init()
    }
    A.prototype.init = function() {
        var vm = this
    }
    var newa = new A()

    var a = Array.prototype,
        proObj = Object.create(a),
        args = Array.prototype.slice
    // console.log(args)


    // var arguments = 2
    // var oraginArr = Array.prototype,
    // oraginobj = Object.create(oraginArr)

    // console.log(oraginobj)
    // var arrMethods = Object.create(oraginArr)





    // console.log(A.__proto__===a.prototype)//true
    // console.log(A)
    // console.log(a.prototype)
    // console.log(a.prototype.__proto__===Object.prototype)//true

    // console.log(Object.prototype.__proto__)//null Object.prototype最顶层
    // a.prototype.c = 3
    // console.log(a.prototype)
    // console.log(A)

    // console.log(A.hasOwnProperty('aa'))
    // console.log(A.hasOwnProperty('c'))
    // console.log('c' in A)
    // console.log('aa' in A)

    function red(agesarr) {
        return agesarr.reduce((prev, curv, index) => {
            return prev + curv
        })
    }
    // console.log(red(agesarr))
    let objs = {
        name: 'Tome',
        age: 10,
        sex: 'men'
    }
    let sa = {
        ...objs
    }
    // console.log(sa)



    class Person {
        constructor(name, age) {
            this.name = name
            this.age = age
        }
        speak() {

        }
    }
    let p1 = new Person('小明', 18)
    p1.speak()
    // 参数相同时可用继承的方法
    // class Student extends Person {} 
    // let st1 = new Student('香港', 100)
    // console.log(st1)

    // 参数不相同时可用继承的方法
    class Student extends Person {
        constructor(name, age, grade) {
            super(name, age) //super 必须写在最前面
            this.grade = grade
        }
        dome() {
            // console.log(this.name, this.age, this.grade)
        }
    }
    let st2 = new Student('台湾', 200, 20)
    // console.log(st2)
    st2.dome()
</script>

<!-- <script src="./src/ts/index.ts"></script> -->